package com.simpou.commons.model.validation;

import com.simpou.commons.utils.lang.Conditionals;
import com.simpou.commons.utils.reflection.Casts;

import java.util.HashSet;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;


/**
 * Auxilia nas operações de validação de beans.
 *
 * @author jonas.pereira
 * @since 17/01/13
 */
public class ValidatorHelper {
    /**
     * Objeto representante da não ocorrência de violações.
     */
    private static final Set<ConstraintViolation<?>> EMPTY_VIOLATIONS = new HashSet<ConstraintViolation<?>>(0);

    /**
     * Implementação do validador do Beans Validation.
     */
    private static final Validator VALIDATOR;

    static {
        final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        VALIDATOR = factory.getValidator();
    }

    /**
     * Valida um bean segundo regras definidas via beans validation (JSR 303).
     *
     * @param bean Bean a ser validado. Seus atributos devem definir anotações
     * do beans validation.
     * @return Erros de validação se houverem ou lista vazia.
     */
    public static <T> Set<ConstraintViolation<T>> invokeBeansValidation(
        final T bean) {
        // normalmente isso não retorna null, mas é possível que alguma 
        // implementação o faça
        final Set<ConstraintViolation<T>> errors = VALIDATOR.validate(bean);

        if (Conditionals.isEmpty(errors)) {
            return Casts.simpleCast(EMPTY_VIOLATIONS);
        } else {
            return errors;
        }
    }
}
